#!/usr/bin/env python3
# encoding=utf-8
import os
import sys
import re
import datetime
from bs4 import BeautifulSoup
import email.parser, email.policy
from commom_api import get_filter_info, get_workday_range, get_doc_dirpath, get_product_name_prefix
import logging
logger = logging.getLogger(__name__)

prefilterinfo = {}

def filter_folders_by_filelist(emailfloders):
    matchfloder = []
    if len(emailfloders) <= 0:
        return None
    for floder in emailfloders:
        fname = floder.split('/')
        if len(fname) < 2:
            continue
        docpath = get_doc_dirpath()
        files = os.listdir(docpath) 
        if len(prefilterinfo['debugmode']) == 0:
            for file in files:
                if file.find(fname[1]) < 0:
                    continue
                if floder not in matchfloder:
                    matchfloder.append(floder)
        else:
            for file in files:
                if fname[1] not in prefilterinfo['debugmode']:
                    continue
                if file.find(fname[1]) < 0:
                    continue
                if floder not in matchfloder:
                    matchfloder.append(floder)
    return matchfloder


def filter_info_init():
    global prefilterinfo
    prefilter = {}
    deffilter = get_filter_info()
    for key, val in deffilter.items():
        if key == 'sender':
            prefilter[key] = val
        elif key == 'date':
            prefilter[key] = val
        elif key == 'title':
            prefilter[key] = val
        elif key == 'debugmode':
            prefilter[key] = val
    mindate = None
    daterange = []
    if 'date' in prefilter.keys():
        for one in prefilter['date']:
            one = one.split(' : ')
            stday = datetime.datetime.strptime(one[0], "%Y-%m-%d")
            if len(one) == 1:
                stday, endday = get_workday_range(stday)
            elif len(one) == 2:
                endday = datetime.datetime.strptime(one[1], "%Y-%m-%d")
                endday = endday + datetime.timedelta(hours=23, minutes=59)
            else:
                continue
            if mindate == None or mindate > stday:
                mindate = stday
            daterange.append((stday, endday))
    else:
        mindate, endday = get_workday_range(datetime.datetime.today())
        daterange.append((mindate, endday))
    prefilter['date'] = daterange
    prefilter['mindate'] = mindate
    prefilterinfo = prefilter
    logging.info(prefilterinfo)

def filter_by_title_info(title, titlelist):
    pairlist = [False]
    if 'include' in titlelist:
        pairlist = [True if title.find(one) >= 0 else False for one in titlelist['include']]
    return any(pairlist)

def filter_by_sender_info(msg, senderlist):
    for sender in senderlist:
        if msg['From'].find(sender) >= 0:
            return True
    return False

def filter_by_date_info(msg, datelist, mindate):
    try:
        data = msg['Received'].split(';')[-1]
    except:
        try:
            data = msg['Date']
        except:
            logger.info(msg)
            return -1
    # logger.info(data)
    # print(data)
    try:
        try:
            # Fri, 27 Dec 2024 14:00:42 +0800
            emaildate = datetime.datetime.strptime(data, ' %a, %d %b %Y %H:%M:%S +0800')
        except:
            # Tue, 14 Jan 2025 16:18:21 +0800
            emaildate = datetime.datetime.strptime(data, '%a, %d %b %Y %H:%M:%S +0800')
    except:
        # Fri, 27 Dec 2024 14:08:17 +0800 (CST)
        emaildate = datetime.datetime.strptime(data, ' %a, %d %b %Y %H:%M:%S +0800 (CST)')
    # print(emaildate)
    # logger.info(emaildate)
    
    
    for (stday, enday) in datelist:
        if emaildate >= stday and emaildate <= enday:
            return 1
    if emaildate < mindate:
        return -1;
    return 0

def is_mail_filter_info(msg, usefilter=1):
    if type(msg) == bytes:
        msg = email.parser.BytesParser(policy=email.policy.default).parsebytes(msg)
    if usefilter == 0:
        return 1
    
    global prefilterinfo
    if 'date' in prefilterinfo :
        ret = filter_by_date_info(msg, prefilterinfo['date'], prefilterinfo['mindate'])
        if ret < 0:
            return -1
        elif ret == 0:
            return 0
    if 'title' in prefilterinfo and filter_by_title_info(msg['Subject'], prefilterinfo['title']) == False:
        return 0
    logger.debug(msg['Subject'])
    if 'sender' in prefilterinfo and filter_by_sender_info(msg, prefilterinfo['sender']) == False:
        return 0
    logger.debug(msg['From'])
    return 1

def parser_context_get_html(msg):
    if msg.is_multipart():
        for part in msg.walk():
            if part.get_content_type() == "text/html":
                htmltext = part.get_payload(decode=True)
    else:
        htmltext = msg.get_payload(decode=True)
    return htmltext

def parser_context_info(data):
    if type(data) == bytes:
        msg = email.parser.BytesParser(policy=email.policy.default).parsebytes(data)
    htmltext = parser_context_get_html(msg)
    # logger.info(htmltext)
    soup = BeautifulSoup(htmltext, "html.parser")
    table = soup.find_all("tr")
    tblen = len(table)
    if tblen < 2:
        logger.info(msg['Subject'] + " error table len " + str(tblen))
        return None
    rows0 = table[0].find_all("td")
    if len(rows0) == 0:
        rows0 = table[0].find_all("th")
    uinfo = []
    for i in range(1, tblen):
        tableinfo = {}
        rows1 = table[i].find_all("td")
        if len(rows1) == 0:
            rows1 = table[i].find_all("td")
        for key,val in zip(rows0, rows1):
            tableinfo[key.get_text()] = val.get_text()
        uinfo.append(user_care_info(tableinfo))
    logger.debug(tableinfo)
    return uinfo

def user_care_info(info):
    if isinstance(info, dict) != True:
        logger.error("info not dict")
        sys.exit()
    deffilter = get_filter_info()
    if 'table' not in deffilter.keys():
        logger.error("not ruler to prase table data")
        sys.exit()

    table = None
    for rule in deffilter['table']:
        subrule = rule.copy()
        del subrule['benchmark']
        if set(subrule.values()).issubset(info.keys()):
            table = rule
            break
    if table == None:
        return None
    
    uinfo = {}
    for key,val in table.items():
        if isinstance(val, list):
            uinfo[key] = val
        else:
            uinfo[key] = info[val]
    if 'date' in uinfo:
        uinfo['date'] = uinfo['date'].replace('年', '-').replace('月', '-').replace('日', '')
    if 'code' in uinfo:
        uinfo['code'] = re.match(r'^[A-Za-z0-9]*', uinfo['code']).group(0)

    global prefilterinfo
    logger.debug(f"uinfo is {uinfo}")
    name = get_product_name_prefix(uinfo['name'])
    if len(prefilterinfo['debugmode']) and name not in prefilterinfo['debugmode']:
        return None
    cdate = datetime.datetime.strptime(uinfo['date'], "%Y-%m-%d")
    inrange = 0
    for (stday, enday) in prefilterinfo['date']:
        if cdate >= stday and cdate <= enday:
            inrange = 1
    if inrange == 0:
        return None
    return uinfo